#include "GC9A01.h"
#include "spi.h"
// 使用硬件片选
#define HARDWARE_CS

#ifndef HARDWARE_CS
void GC9A01_CS_ON(void)
{
    CS_GPIO_Port->BSRR = CS_Pin; // 将CS引脚拉低
}
void GC9A01_CS_OFF(void)
{
    CS_GPIO_Port->BRR = CS_Pin; // 将CS引脚拉高
}
#endif
void GC9A01_DC_ON(void)
{
    DC_GPIO_Port->BSRR = DC_Pin; // 将DC引脚拉高
}
void GC9A01_DC_OFF(void)
{
    DC_GPIO_Port->BRR = DC_Pin; // 将DC引脚拉低
}
void GC9A01_Reset_ON(void)
{
    Reset_GPIO_Port->BSRR = Reset_Pin; // 将Reset引脚拉高
}
void GC9A01_Reset_OFF(void)
{
    Reset_GPIO_Port->BRR = Reset_Pin; // 将Reset引脚拉低
}

void GC9A01_WR(uint8_t *data, size_t len)
{
    // GC9A01_CS_ON(); // 激活片选
    HAL_SPI_Transmit(&hspi1, data, len, 0xffffff);
    // GC9A01_CS_OFF(); // 取消片选
}

void GC9A01_WR_Data(uint8_t *data, size_t len)
{
    GC9A01_DC_ON(); // 设置数据模式
    GC9A01_WR(data, len); // 发送数据
}
void GC9A01_WR_Byte(uint8_t val)
{
    GC9A01_WR_Data(&val, sizeof(val)); // 发送一个字节
}
void GC9A01_WR_Command(uint8_t cmd)
{
    GC9A01_DC_OFF(); // 设置命令模式
    GC9A01_WR(&cmd, sizeof(cmd)); // 发送命令
}

void GC9A01_init(void)
{
    // 复位显示屏
    GC9A01_Reset_OFF();
    HAL_Delay(10);
    GC9A01_Reset_ON();
    HAL_Delay(120);

    // 初始化显示屏
    GC9A01_WR_Command(0xEF);

    GC9A01_WR_Command(0xEB);
    GC9A01_WR_Byte(0x14);

    GC9A01_WR_Command(0xFE);
    GC9A01_WR_Command(0xEF);

    GC9A01_WR_Command(0xEB);
    GC9A01_WR_Byte(0x14);

    GC9A01_WR_Command(0x84);
    GC9A01_WR_Byte(0x40);

    GC9A01_WR_Command(0x85);
    GC9A01_WR_Byte(0xFF);

    GC9A01_WR_Command(0x86);
    GC9A01_WR_Byte(0xFF);

    GC9A01_WR_Command(0x87);
    GC9A01_WR_Byte(0xFF);

    GC9A01_WR_Command(0x88);
    GC9A01_WR_Byte(0x0A);

    GC9A01_WR_Command(0x89);
    GC9A01_WR_Byte(0x21);

    GC9A01_WR_Command(0x8A);
    GC9A01_WR_Byte(0x00);

    GC9A01_WR_Command(0x8B);
    GC9A01_WR_Byte(0x80);

    GC9A01_WR_Command(0x8C);
    GC9A01_WR_Byte(0x01);

    GC9A01_WR_Command(0x8D);
    GC9A01_WR_Byte(0x01);

    GC9A01_WR_Command(0x8E);
    GC9A01_WR_Byte(0xFF);

    GC9A01_WR_Command(0x8F);
    GC9A01_WR_Byte(0xFF);

    GC9A01_WR_Command(0xB6);
    GC9A01_WR_Byte(0x00);
    GC9A01_WR_Byte(0x00);

    GC9A01_WR_Command(0x36);

#if ORIENTATION == 0
    GC9A01_WR_Byte(0x18);
#elif ORIENTATION == 1
    GC9A01_WR_Byte(0x28);
#elif ORIENTATION == 2
    GC9A01_WR_Byte(0x48);
#else
    GC9A01_WR_Byte(0x88);
#endif

    GC9A01_WR_Command(COLOR_MODE);
    GC9A01_WR_Byte(COLOR_MODE__16_BIT);

    GC9A01_WR_Command(0x90);
    GC9A01_WR_Byte(0x08);
    GC9A01_WR_Byte(0x08);
    GC9A01_WR_Byte(0x08);
    GC9A01_WR_Byte(0x08);

    GC9A01_WR_Command(0xBD);
    GC9A01_WR_Byte(0x06);

    GC9A01_WR_Command(0xBC);
    GC9A01_WR_Byte(0x00);

    GC9A01_WR_Command(0xFF);
    GC9A01_WR_Byte(0x60);
    GC9A01_WR_Byte(0x01);
    GC9A01_WR_Byte(0x04);

    GC9A01_WR_Command(0xC3);
    GC9A01_WR_Byte(0x13);
    GC9A01_WR_Command(0xC4);
    GC9A01_WR_Byte(0x13);

    GC9A01_WR_Command(0xC9);
    GC9A01_WR_Byte(0x22);

    GC9A01_WR_Command(0xBE);
    GC9A01_WR_Byte(0x11);

    GC9A01_WR_Command(0xE1);
    GC9A01_WR_Byte(0x10);
    GC9A01_WR_Byte(0x0E);

    GC9A01_WR_Command(0xDF);
    GC9A01_WR_Byte(0x21);
    GC9A01_WR_Byte(0x0c);
    GC9A01_WR_Byte(0x02);

    GC9A01_WR_Command(0xF0);
    GC9A01_WR_Byte(0x45);
    GC9A01_WR_Byte(0x09);
    GC9A01_WR_Byte(0x08);
    GC9A01_WR_Byte(0x08);
    GC9A01_WR_Byte(0x26);
    GC9A01_WR_Byte(0x2A);

    GC9A01_WR_Command(0xF1);
    GC9A01_WR_Byte(0x43);
    GC9A01_WR_Byte(0x70);
    GC9A01_WR_Byte(0x72);
    GC9A01_WR_Byte(0x36);
    GC9A01_WR_Byte(0x37);
    GC9A01_WR_Byte(0x6F);

    GC9A01_WR_Command(0xF2);
    GC9A01_WR_Byte(0x45);
    GC9A01_WR_Byte(0x09);
    GC9A01_WR_Byte(0x08);
    GC9A01_WR_Byte(0x08);
    GC9A01_WR_Byte(0x26);
    GC9A01_WR_Byte(0x2A);

    GC9A01_WR_Command(0xF3);
    GC9A01_WR_Byte(0x43);
    GC9A01_WR_Byte(0x70);
    GC9A01_WR_Byte(0x72);
    GC9A01_WR_Byte(0x36);
    GC9A01_WR_Byte(0x37);
    GC9A01_WR_Byte(0x6F);

    GC9A01_WR_Command(0xED);
    GC9A01_WR_Byte(0x1B);
    GC9A01_WR_Byte(0x0B);

    GC9A01_WR_Command(0xAE);
    GC9A01_WR_Byte(0x77);

    GC9A01_WR_Command(0xCD);
    GC9A01_WR_Byte(0x63);

    GC9A01_WR_Command(0x70);
    GC9A01_WR_Byte(0x07);
    GC9A01_WR_Byte(0x07);
    GC9A01_WR_Byte(0x04);
    GC9A01_WR_Byte(0x0E);
    GC9A01_WR_Byte(0x0F);
    GC9A01_WR_Byte(0x09);
    GC9A01_WR_Byte(0x07);
    GC9A01_WR_Byte(0x08);
    GC9A01_WR_Byte(0x03);

    GC9A01_WR_Command(0xE8);
    GC9A01_WR_Byte(0x34);

    GC9A01_WR_Command(0x62);
    GC9A01_WR_Byte(0x18);
    GC9A01_WR_Byte(0x0D);
    GC9A01_WR_Byte(0x71);
    GC9A01_WR_Byte(0xED);
    GC9A01_WR_Byte(0x70);
    GC9A01_WR_Byte(0x70);
    GC9A01_WR_Byte(0x18);
    GC9A01_WR_Byte(0x0F);
    GC9A01_WR_Byte(0x71);
    GC9A01_WR_Byte(0xEF);
    GC9A01_WR_Byte(0x70);
    GC9A01_WR_Byte(0x70);

    GC9A01_WR_Command(0x63);
    GC9A01_WR_Byte(0x18);
    GC9A01_WR_Byte(0x11);
    GC9A01_WR_Byte(0x71);
    GC9A01_WR_Byte(0xF1);
    GC9A01_WR_Byte(0x70);
    GC9A01_WR_Byte(0x70);
    GC9A01_WR_Byte(0x18);
    GC9A01_WR_Byte(0x13);
    GC9A01_WR_Byte(0x71);
    GC9A01_WR_Byte(0xF3);
    GC9A01_WR_Byte(0x70);
    GC9A01_WR_Byte(0x70);

    GC9A01_WR_Command(0x64);
    GC9A01_WR_Byte(0x28);
    GC9A01_WR_Byte(0x29);
    GC9A01_WR_Byte(0xF1);
    GC9A01_WR_Byte(0x01);
    GC9A01_WR_Byte(0xF1);
    GC9A01_WR_Byte(0x00);
    GC9A01_WR_Byte(0x07);

    GC9A01_WR_Command(0x66);
    GC9A01_WR_Byte(0x3C);
    GC9A01_WR_Byte(0x00);
    GC9A01_WR_Byte(0xCD);
    GC9A01_WR_Byte(0x67);
    GC9A01_WR_Byte(0x45);
    GC9A01_WR_Byte(0x45);
    GC9A01_WR_Byte(0x10);
    GC9A01_WR_Byte(0x00);
    GC9A01_WR_Byte(0x00);
    GC9A01_WR_Byte(0x00);

    GC9A01_WR_Command(0x67);
    GC9A01_WR_Byte(0x00);
    GC9A01_WR_Byte(0x3C);
    GC9A01_WR_Byte(0x00);
    GC9A01_WR_Byte(0x00);
    GC9A01_WR_Byte(0x00);
    GC9A01_WR_Byte(0x01);
    GC9A01_WR_Byte(0x54);
    GC9A01_WR_Byte(0x10);
    GC9A01_WR_Byte(0x32);
    GC9A01_WR_Byte(0x98);

    GC9A01_WR_Command(0x74);
    GC9A01_WR_Byte(0x10);
    GC9A01_WR_Byte(0x85);
    GC9A01_WR_Byte(0x80);
    GC9A01_WR_Byte(0x00);
    GC9A01_WR_Byte(0x00);
    GC9A01_WR_Byte(0x4E);
    GC9A01_WR_Byte(0x00);

    GC9A01_WR_Command(0x98);
    GC9A01_WR_Byte(0x3e);
    GC9A01_WR_Byte(0x07);

    GC9A01_WR_Command(0x35);
    GC9A01_WR_Command(0x21);

    GC9A01_WR_Command(0x11);
    HAL_Delay(120);
    GC9A01_WR_Command(0x29);
    HAL_Delay(20);
}

void GC9A01_Set_Frame(uint16_t x_start, uint16_t y_start, uint16_t x_end, uint16_t y_end)
{
    // 设置列地址
    GC9A01_WR_Command(COL_ADDR_SET);  // 0x2A
    uint8_t data[4];
    data[0] = x_start >> 8;     // xstart高八位
    data[1] = x_start & 0xFF;   // xstart低八位
    data[2] = x_end >> 8;       // xend高八位
    data[3] = x_end & 0xFF;     // xend低八位
    GC9A01_WR_Data(data, sizeof(data));

    // 设置行地址
    GC9A01_WR_Command(ROW_ADDR_SET);  // 0x2B
    data[0] = y_start >> 8;     // ystart高八位
    data[1] = y_start & 0xFF;   // ystart低八位
    data[2] = y_end >> 8;       // yend高八位
    data[3] = y_end & 0xFF;     // yend低八位
    GC9A01_WR_Data(data, sizeof(data));
}